package com.corewillsoft.fireflies.gameobjects.obstacles;

import com.corewillsoft.fireflies.gameobjects.GameObject;
import com.corewillsoft.fireflies.gameobjects.obstacles.trajectories.Trajectory;

import java.util.*;

public abstract class Obstacle extends GameObject implements ITrajectory {

	/**
	 * Enumeration with all possible types of obstacle
	 */
	public static enum ObstacleType {
		FROG, HORNET, FAN, WALL,
	}

	/**
	 * Enumeration with all possible variable parameters of obstacle (which can be set to obstacle from DB)
	 */
	public static enum ObstacleParameterType {
		SIZE, TRAJECTORY
	}

	/**
	 * List of obstacle's parameters of particular type (for example, parameters of obstacle's trajectory)
	 */
	public static class ObstacleParametersList extends ArrayList<Float> {
		private static final long serialVersionUID = -6049432120251198455L;
	}

	/**
	 * Map containing all parameters of the obstacle of different types;
	 * key of this map's element is type of parameters set, value is list of parameters of this type
	 */
	public static class ObstacleParameters extends HashMap<ObstacleParameterType, ObstacleParametersList> {
		private static final long serialVersionUID = -8078873722595729341L;
	}

	protected ObstacleType type;

	/**
	 * Trajectory of the obstacle; should be injected by calling {@link Obstacle#setTrajectory(com.corewillsoft.fireflies.gameobjects.obstacles.trajectories.Trajectory)} when obstacle is created;
	 * trajectory class calculates speed components of obstacle according to its current position
	 */
	protected Trajectory trajectory;

	/**
	 * All obstacle configurable parameters of different types;
	 * key of this map's element is type of parameters set, value is list of parameters of this type
	 */
	protected ObstacleParameters parametersMap;

	public Obstacle() {
		super(0, 0);
	}

	public Obstacle(int x, int y) {
		super(x, y);
	}

	public void setTrajectory(Trajectory trajectory){
		this.trajectory = trajectory;
	}

	@Override
	abstract public void updateState();

	abstract public ObstacleType getType();

	public ObstacleParameters getParametersMap() {
		return parametersMap;
	}

	public void setParametersMap(ObstacleParameters parametersMap) {
		this.parametersMap = parametersMap;
	}
	
	@Override
	public void parameterChanged(int parameterIndex, Float parameterValue) {
		//get old parameters list of the obstacle for TRAJECTORY type
		ObstacleParametersList trajectoryParameters = parametersMap.get(ObstacleParameterType.TRAJECTORY);

		/*
		set updated parameter value to parameters list of the obstacle;
		real index of parameter is +1, because parameters list passed to Trajectory instance
		lacked first parameter - trajectory type
		 */
		trajectoryParameters.set(parameterIndex + 1, parameterValue);
	}
}